<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<button onclick="tree()">
    给我一拳！
</button>
</body>
</html>
<script>
    let list = [//模拟sql查出来的列表。
        {id:2,name:'child',lft:2,rgt:7,level:2},
        {id:3,name:'grandson',lft:3,rgt:4,level:3},
        {id:1,name:'root',lft:1,rgt:8,level:1},
        {id:4,name:'grandson2',lft:5,rgt:6,level:3}
    ];
    let rights = [] /*类似于一个栈结构（后进先出）*/
    let mp = {}
    function tree (){
        list.sort((a,b) => a.lft - b.lft)//如果你在sql中没有进行排序，需要在这里给他排序。
        list.forEach(item => {
            if(rights.length > 0) {
                while(rights[rights.length-1] < item.rgt) {
                    rights.splice(-1, 1)//从rights末尾去除
                }
            }
            let _level = rights.length;
            item._level = _level;
            mp[_level] = item.id
            item.parent_id = _level - 1 in mp ? mp[_level - 1] : null;//计算出上级部门编号
            item.is_leaf = item.lft === item.rgt - 1;//判断是否叶子部门
            rights.push(item.rgt)
        })

        /*上级部门计算出来了，和存parent_id的效果就一样了，后面只需要递归即可*/
        /*递归函数 示例*/
        let recursive = (_list, parent_id = null) => {
            let _tree = [];
            _list.forEach(item => {
                if(item.parent_id == parent_id) {
                    let childs = recursive(_list, item.id)
                    _tree.push({
                        ...item,
                        children: childs.length > 0 ? childs : (item.isLeaf ? null : [])
                    })
                }
            })
            return _tree
        }
        console.log(recursive(list))
    }
</script>